通过java自带的工具和linux命令来分析死锁

  当我们编写java程序时,由于不合理的设计,可能会出现程序死循环/死锁问题。

下面我就以程序的死锁为例,来进行分析

我编写的测试类是Run类

1.查找Run类对应的PID,使用命令:ps -ef | grep Run

 

gl    6765  4121  0 13:52 ?        00:00:00 /opt/java/jdk1.8.0_101/bin/java -Dfile.encoding=UTF-8 -classpath /home/lupeng/java_development/MultiThread/bin Run
gl    6795  2766  0 13:53 pts/0    00:00:00 grep --color=auto Run

 

 

2.利用java自带的工具jstack进行分析

jstack 6765

结果如下

 

Java stack information for the threads listed above:
===================================================
"Thread-1":
	at DeadThread.run(DeadThread.java:37)
	- waiting to lock <0x00000000ec1df068> (a java.lang.Object)
	- locked <0x00000000ec1df078> (a java.lang.Object)
	at java.lang.Thread.run(Thread.java:745)
"Thread-0":
	at DeadThread.run(DeadThread.java:21)
	- waiting to lock <0x00000000ec1df078> (a java.lang.Object)
	- locked <0x00000000ec1df068> (a java.lang.Object)
	at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.


deadlock说明出现死锁问题。

 

Thread-1 已经获得了锁<0x00000000ec1df078>,同时等待锁<0x00000000ec1df078>

Thread-0已经获得了锁<0x00000000ec1df078>,同时等待锁<0x00000000ec1df078>

一次发生了死锁问题。

 

Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x00007fefcc003828 (object 0x00000000ec1df068, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x00007fefcc006218 (object 0x00000000ec1df078, a java.lang.Object),
  which is held by "Thread-1"

 

 

 

 

 

那么到底时什么地方出现了死锁问题呢?

我们再来分析下

 

Java stack information for the threads listed above:
===================================================
"Thread-1":
	at DeadThread.run(DeadThread.java:37)
	- waiting to lock <0x00000000ec1df068> (a java.lang.Object)
	- locked <0x00000000ec1df078> (a java.lang.Object)
	at java.lang.Thread.run(Thread.java:745)
"Thread-0":
	at DeadThread.run(DeadThread.java:21)
	- waiting to lock <0x00000000ec1df078> (a java.lang.Object)
	- locked <0x00000000ec1df068> (a java.lang.Object)
	at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.

其中有一行是at DeadThread.run(DeadThread.java:37)

 

说明Thread-1实在DeadThread类的37行处发生死锁

其中at DeadThread.run(DeadThread.java:21)

说明Thread-0实在DeadThread类的21行处发生死锁
接下来我们定位到具体代码:

 

public class DeadThread implements Runnable{
	public String username;
	public Object lock1 = new Object();
	public Object lock2 = new Object();
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		if(username.equals("a")){
			synchronized (lock1) {
				try {
					System.out.println("username = "+username);
					System.out.println(Thread.currentThread().getName());
					Thread.sleep(3000);
				} catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}
				synchronized (lock2) {
					System.out.println("按lock1->lock2的顺序执行代码");
				}
			}
		}
		if(username.equals("b")){
			synchronized (lock2) {
				try{
						System.out.println("username = "+username);
						System.out.println(Thread.currentThread().getName());
						Thread.sleep(3000);
					
				}catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}
				synchronized (lock1) {
					System.out.println("按lock2->lock1顺序执行代码");
				}
			}
			
		}
	}
	
	public void setFlag(String username){
		this.username=username;
	}
}

 

 

从而定位到死锁发生的原因,及具体位置:

Thread-0获得了锁lock1,接下来期望获得锁lock2,(20)

但是此时Thread-1获得了锁lock2,接下来期望获得锁lock2,(37)

因而发生了死锁。
 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值